home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / HDX_BACK / HDX401.ATB / HDX.BK < prev    next >
Encoding:
Text File  |  2001-02-09  |  22.7 KB  |  937 lines

  1. /* hdx.c */
  2.  
  3. /*
  4.  * Atari Hard Disk Installation Utility
  5.  * Copyright 1988 Atari Corp.
  6.  *
  7.  * Associated files
  8.  *    hdx.rsc        resource file
  9.  *    wincap        hard disk database (text file)
  10.  *
  11.  *    hdx.h        object tree definitions
  12.  *    defs.h        constant definitions
  13.  *    part.h        ST structure definitions
  14.  *    ipart.h        IBM structure definitions
  15.  *
  16.  *    hdx.c        top level, user interface (this file)
  17.  *    epart.c        edit partition sizes
  18.  *    fmt.c        disk formatting
  19.  *    part.c        partition reading/writing
  20.  *    sect.c        sector reading, writing, zeroing
  21.  *    string.c    string functions (matching, concat, ...)
  22.  *    assist.c    markbad(), zero()
  23.  *    wincap.c    hard disk parameter / partition size database
  24.  *    st.c        random ST functions (delay, reboot, ...)
  25.  *
  26.  *----
  27.  * 11-May-1988    ml.    Cleaned up the memory management in the program
  28.  *            (ie. for all files).  Memory chunks which are for
  29.  *            sure will be < 32k is allocated using malloc(),
  30.  *            whereas chunks >= 32k is allocated using Malloc().
  31.  *            When using malloc(), you will get the 'Stack Over-
  32.  *            flow message if you are in Supervisor mode and 
  33.  *            you have your own supervisor stack.  To get around
  34.  *            this, have to use mymalloc() (in mymalloc.s).
  35.  * 15-Mar-1988    ml.    Changed interface to Markbad.
  36.  * 11-Jan-1988    ml.    Modified dialogue boxes.
  37.  * 07-Dec-1987    ml.    Started to add in concept of Bad Sector List.
  38.  * ??-Oct-1987  ml.    Partition and Disk type menu now has 15 entries 
  39.  *            instead of 16.
  40.  * 30-Sep-1987    ml.    Inherited 'this' from Landon Dyer.
  41.  * 24-Mar-1986 lmd    Released to software test.
  42.  * 15-Mar-1986 lmd    Hacked up from earlier version by Jim Tittsler.
  43.  * 8-Nov-1988  jye. change and add some codes so that can be used for extended
  44.  *                    and big partition.
  45.  * 13-Jun-1989 jye. Change and add some codes so that HDX can be deal with
  46.  *                    acsi and scsi drives.
  47.  * 22-Jan-1990 jye. Change the HDX so that we don't have to put a informations
  48.  *                    of a drive into the Wincap file.
  49.  * 13-Mar-1990 jye. change the HDX to a genetic one so that the user don't
  50.  *                    need know what kind of drive.
  51.  * 20-Jul-1990 jye. change the interface about the unit select. In the new 
  52.  *                    interface, user tells the type of drive is acsi or scsi,
  53.  *                    then selects unit.
  54.  * 01-Aug-1990 jye. Change hard disk size request from mdsence to readcap.
  55.  * 25-Jul-1991 jye. Change the Hdx so that can be used for IDE-AT drive.
  56.  *
  57.  */
  58.  
  59. #include "obdefs.h"
  60. #include "gemdefs.h"
  61. #include "osbind.h"
  62. #include "mydefs.h"
  63. #include "part.h"
  64. #include "bsl.h"
  65. #include "hdx.h"
  66. #include "addr.h"
  67. #include "myerror.h"
  68.  
  69. #define MFM 17
  70.  
  71. extern char sbuf[];
  72. extern int rebootp;
  73. extern long gbslsiz();
  74. extern long get3bytes();
  75. extern long get4bytes();
  76. extern long bslsiz;
  77. extern BYTE *bsl;
  78. extern int uplim;            /* the number of partitions */
  79. extern long sptrk;
  80. extern long spcyl;
  81. extern int ibmpart;
  82. extern int yesscan;
  83. extern long disksiz;
  84. extern long ratio;
  85. extern int typedev;
  86. extern int typedrv;
  87. extern int prevnpart;
  88. extern int atexst;        /* set for AT drive exist */
  89.  
  90. /* Globals */
  91. int rebootp = 0;    /* 1: must reboot (not return to desktop) */
  92. int tformat;            /* TRUE: just formatted disk */
  93. int running;        /* 1: continue evnt_multi() loop */
  94. char sbuf[512];        /* error message buffer */
  95. long extsiz;        /* the size of extened partition */
  96. long ostack;                /* old stack pointer */
  97. int toibm;            /* the flag of partition to ibm format */
  98. int ibm2st;            /* the flag for IBM partition to ST */
  99. long bps;            /* bytes per sector */
  100. int npart;            /* number of partition */
  101. int ext;            /* the index of extended partition */
  102. int extend;            /* the index of end extended partition */
  103. int showmany;        /* the flag that show the too much device alert box */
  104. char ttscsi;        /* SCSI hard disk drive */
  105. int noacsi;            /* set for no ACSI dirve in the system */
  106. int needscan;        /* TRUE: if info in the LOGMAP update */
  107. int noinfo;            /* 1: no informations in the wincap */
  108. int athead;            /* the # of data heads on the AT drive */
  109. int atcyl;            /* the # of cylinders on the AT drive */
  110. int atspt;            /* the # of sectors per track on the AT drive */
  111. int atshead;        /* the # of data heads on the AT slave drive */
  112. int atscyl;            /* the # of cylinders on the AT slave drive */
  113. int atsspt;            /* the # of sectors per track on the AT slave drive */
  114.  
  115. /*  Logical-to-dev+partition mapping table. */
  116. extern char cachexst;        /* 0: no cache. 1: with cache */
  117.  
  118. /* AES (windows and messages) related variables */
  119. int gl_hchar;        /* height of system font (pixels) */
  120. int gl_wchar;        /* width of system font (pixels) */
  121. int gl_wbox;        /* width of box able to hold system font */
  122. int gl_hbox;        /* height of box able to hold system font */
  123.  
  124. int phys_handle;    /* physical workstation handle */
  125. int handle;        /* virtual workstation handle */
  126. int wi_handle;        /* window handle */
  127.  
  128. int formw, formh, sx, sy, lx, ly;    /* dialogue box dimensions */
  129. int xdesk, ydesk, hdesk, wdesk;        /* window X, Y, width, height */
  130. int xwork, ywork, hwork, wwork;        /* desktop and work areas */
  131.  
  132. int msgbuff[8];        /* event message buffer */
  133. int keycode;        /* keycode returned by event-keyboard */
  134. int mx, my;        /* mouse x and y pos. */
  135. int butdown;        /* button state tested for, UP/DOWN */
  136. int ret;        /* dummy return variable */
  137. int pnf;        /* 1: partition or format; 0: zero or markbad */
  138. int hidden;        /* current state of cursor */
  139. int contrl[12];
  140. int intin[128];
  141. int ptsin[128];
  142. int intout[128];
  143. int ptsout[128];    /* storage wasted for idiotic bindings */
  144. int work_in[11];    /* Input to GSX parameter array */
  145. int work_out[57];    /* Output from GSX parameter array */
  146. int pxyarray[10];    /* input point array */
  147.  
  148. /*
  149.  * Top level;
  150.  * we get control from the desktop.
  151.  */
  152. main()
  153. {
  154.     pnf = 0;        /* set the flag to it isn't partition yet */
  155.     appl_init();
  156.     phys_handle=graf_handle(&gl_wchar, &gl_hchar, &gl_wbox, &gl_hbox);
  157.     wind_get(0, WF_WORKXYWH, &xdesk, &ydesk, &wdesk, &hdesk);
  158.     open_vwork();
  159.     wi_handle=wind_create(0x0040&0x0080, xdesk, ydesk, wdesk, hdesk);
  160.  
  161.     hidden = FALSE;
  162.     butdown = TRUE;
  163.  
  164.     /* doing a checking see if the cache in the system */
  165.     cachexst = (char) chkcache();
  166.  
  167.     rsrc_load(RESOURCEFILE);
  168.     /* Get all addresses of dialogues from resource file */
  169.     getalladdr();
  170.  
  171.     needscan = TRUE;
  172.  
  173.        domulti();
  174.  
  175.     reboot();
  176.  
  177.     wind_delete(wi_handle);
  178.     v_clsvwk(handle);
  179.     appl_exit();
  180. }
  181.  
  182.  
  183. /*
  184.  * Get a single event, process it, and return.
  185.  *
  186.  */
  187. domulti(){
  188.     int event;
  189.     
  190.     /*
  191.     event = evnt_multi(MU_MESAG,
  192.             1,1,butdown,
  193.             0,0,0,0,0,
  194.             0,0,0,0,0,
  195.             msgbuff,0,0,&mx,&my,&ret,&ret,&keycode,&ret);
  196.  
  197.  
  198.     */
  199.             wind_update(TRUE);
  200.             BEE_MOUSE;
  201.             if (rescan(0,0) != OK) {
  202.                 errs("[3][|", CANTFMT, "][ EXIT ]");
  203.                 goto fnshfmt;
  204.             }
  205.             tformat = TRUE;
  206.             needscan = FALSE;
  207.             if ((ret = dodiform()) != OK)
  208.                 if (ret == ERROR)
  209.                     errs("[3][|", CANTFMT, "][ EXIT ]");
  210.             else 
  211.                 errs("[1][|", OKFMT, "][ EXIT ]");
  212.     fnshfmt:
  213.             tformat = FALSE;
  214.                wind_update(FALSE);
  215. }
  216.  
  217.  
  218.  
  219. /*
  220.  * Handle [FORMAT] item.
  221.  *
  222.  */
  223. dodiform()
  224. {
  225.   extern char bootstop;
  226.   extern char bootend;
  227.   int dev, v, w, i, ret;
  228.   int modesel;            /* flag for mode select */
  229.   long cnt, hdsiz;
  230.   char *s, *d, *wgetstr();
  231.   char buf[10], bs[512]; 
  232.   char *seldev =  "IDE  unit 0";
  233.   long nbad;
  234.   extern long gbslsiz(), nument(), dsmarkbad();
  235.   long pattern, temp;
  236.   long longrandom();
  237.   int set, bsiz;
  238.   
  239.   /*
  240.    * Throw up generic formatting/partition warning,
  241.    * then get physical dev they want to clobber.
  242.    */
  243.   yesscan = 0;
  244.   noinfo = 0;
  245.   /*
  246.   fwarning[FWARNCN].ob_state = NORMAL;
  247.   fwarning[FWARNOK].ob_state = NORMAL;
  248.   if (execform(fwarning) != FWARNOK) return 10;
  249.   */
  250.   ARROW_MOUSE;
  251.   ret = form_alert(1, "[3][    Format a Physical Unit| |           WARNING!|Formatting a physical unit will| destroy all information on it.][OK|CANCEL]");
  252.   BEE_MOUSE;
  253.   if (ret == 2)
  254.       return 10;
  255.   dev = 0;
  256.   pattern = longrandom();  /* can't find pattern from wincap, make one */
  257.  
  258.   /* For REAL !! */  
  259.   /*
  260.   dsplymsg(fmtmsg);
  261.   */
  262.   form_alert(0, "[0][Format a Physical Unit| | |Formatting...][]");
  263.  
  264.   bsl = 0L;
  265.   
  266.   /* Get size of Bad Sector List */
  267.   if ((bslsiz = gbslsiz(dev)) > 0L) {
  268.       /* Allocate memory for existing BSL */
  269.       if ((bsl = (BYTE *)mymalloc((int)bslsiz*512)) <= 0) {
  270.           ret = ERROR;
  271.           goto formend;
  272.       }
  273.       
  274.       /* Read in BSL */
  275.       if ((ret = rdbsl(dev)) != OK) {
  276.           /* Create a new BSL if current one is unusable */
  277.           if (creabsl(dev, NEW, 0L) != OK) {
  278.               ret = ERROR;
  279.               goto formend;
  280.           }
  281.       } else {
  282.             /* Remove USER BSL */
  283.             if (creabsl(dev, EXPAND, nument(VENDOR)) != OK) {
  284.                 ret = ERROR;
  285.                 goto formend;
  286.             }
  287.       }
  288.   } else if (bslsiz == 0L || bslsiz == ERROR) {    /* no bsl or read error */
  289.       if (creabsl(dev, NEW, 0L) != OK) {
  290.           ret = ERROR;
  291.           goto formend;
  292.       }
  293.   } else {    /* bslsiz == MDMERR; medium changed error */
  294.       ret = ERROR;
  295.       goto formend;
  296.   }
  297.   
  298.   /*
  299.    * In supervisor mode
  300.    * set disk format parameters
  301.    * and format the disk.
  302.    */
  303.   ostack = Super(NULL);
  304.   if ((ret = fmtunt(dev)) != OK)    {
  305.       ret = ERROR;
  306.   } else {
  307.       hdsiz = athead*atcyl*atspt;
  308.     disksiz = hdsiz;
  309.   }
  310.   delay();
  311.   Super(ostack);
  312. formend:
  313.   erasemsg();    /* Erase formatting box */
  314.   if (ret < 0) {
  315.       if (bsl > 0) free(bsl);
  316.       return ERROR;
  317.   }
  318.   
  319.   /*------------------------------------------*
  320.    * Markbad the device destructively.          *
  321.    * Bad Sectors found are added to the BSL.  *
  322.    * Write BSL to device.              *
  323.    *------------------------------------------*/
  324.   if ((nbad = dsmarkbad(dev, hdsiz, 1, pattern)) < 0) {
  325.       free(bsl);
  326.       return ERROR;
  327.   }
  328.   if (wrbsl(dev) != OK) {
  329.       free(bsl);
  330.       return ERROR;
  331.   }
  332.   free(bsl);
  333.  
  334.     
  335.   /*
  336.    * Install boot-stopper in sector image;
  337.    * write root sector to device.
  338.    * 6-13-88  Setting of soft format parameters in root sector sets
  339.    *        the hard disk size only.
  340.    */
  341.   fillbuf(bs, 512L, 0L);    /* create new root sector */
  342.   sbslparm(bs);            /* set BSL parameters */
  343.   ((RSECT *)(bs + 0x200 - sizeof(RSECT)))->hd_siz =disksiz;
  344.   for (d = bs, s = &bootstop, cnt = (long)(&bootend - &bootstop); --cnt;)
  345.     *d++ = *s++;
  346.   Protobt(bs, -1L, -1, 1);    /* make root sector executable */
  347.   
  348.   if ((ret = putroot(dev, bs, (SECTOR)0)) != OK) {
  349.       return ERROR;
  350.   }
  351.  
  352.   return (dodipart(dev, disksiz));
  353. }
  354.  
  355.  
  356.  
  357.  
  358. /*
  359.  * Handle [PARTITION] item;
  360.  * if `xdev' is -1, throw up dialog boxes;
  361.  * if `xdev' >= 0, just partition the dev,
  362.  * using `pnam' as the partition type, 
  363.  * and `pr_id' to search for the type.
  364.  *
  365.  */
  366. dodipart(xdev, hsize)
  367. int xdev;
  368. long hsize;
  369. {
  370.     int dev, i, ret =OK, fine;
  371.     int choice;
  372.     char *s;
  373.     char bs[512];
  374.     PART *pinfo;
  375.     int tem1, tem2;
  376.     long disksiz;
  377.  
  378.     npart = 4;
  379.     ext = NO_EXT;    /* set the extended partition flag to not exists */
  380.     dev = xdev;
  381.     if ((pinfo = (PART *)Malloc((long)sizeof(PART)*npart)) <= 0)    {
  382.         if (pinfo > 0)    Mfree(pinfo);
  383.         return ERROR;
  384.     }
  385.     inipart(pinfo, npart);
  386.     npart = 0;
  387.     setpart(pinfo, hsize);
  388.  
  389.     /* For REAL!! */
  390.     /*
  391.     dsplymsg(partmsg);
  392.     */
  393.   form_alert(0, "[0][Format a Physical Unit| | |Partitioning...][]");
  394.     
  395.     bsl = 0L;
  396.     
  397.     /* Get size of BSL */
  398.     if ((bslsiz = gbslsiz(dev)) > 0L) {
  399.         /* Allocate memory for existing BSL */
  400.         if ((bsl = (BYTE *)mymalloc((int)bslsiz*512)) <= 0) {
  401.             ret = ERROR;
  402.             goto partend;
  403.         }
  404.             
  405.         /* Read in BSL */
  406.         if ((ret = rdbsl(dev)) != OK) {
  407.             ret = ERROR;
  408.             goto partend;
  409.         }
  410.     } else if (bslsiz == 0) {
  411.         ret = ERROR;
  412.         goto partend;
  413.     } else if (bslsiz == ERROR) {
  414.         ret = ERROR;
  415.         goto partend;
  416.     } else {
  417.         ret = ERROR;
  418.         goto partend;
  419.     }
  420.  
  421.     
  422.     /* Lay out partition headers */
  423.     if (spheader(dev, &pinfo[0]) != OK) {
  424.         ret = ERROR;
  425.         goto partend;
  426.     }
  427.     
  428.     if (wrbsl(dev) != OK) {        /* write BSL */
  429.         ret = ERROR;
  430.         goto partend;
  431.     }
  432.  
  433.     /* check and change the structure's id after 'spheader()' */
  434.     changeid(pinfo);
  435.  
  436.     /* Shove partition parms into root sector */
  437.     if ((ret = getroot(dev, bs, (SECTOR)0)) != 0)    {
  438.         ret = ERROR;
  439.         goto partend;
  440.     }
  441.  
  442.     if ((ret = stlayroot(bs, dev, pinfo)) != OK)    {
  443.         goto partend;
  444.     }
  445.     tem1 = npart;            /* save the number of partitions */
  446.     tem2 = ext;                /* save the index of extended partition */
  447.     if (rescan(1,0)) {        /* has to be here because map changed    */
  448.         ret = ERROR;        /* after partitions are moved around,    */
  449.         goto partend;        /* report medium change error.        */
  450.     }
  451.     npart = tem1;
  452.     ext = tem2;
  453.     /* Partition the device with parameters given in pinfo */
  454.     ret = stlaybs(dev, &pinfo[0]);
  455.         
  456.     rebootp = 1;
  457.     pnf = 1;        /* set the flag to just doing the partition */
  458. partend:
  459.     if (bsl > 0) free(bsl);
  460.     inipart(pinfo, npart);
  461.     if (pinfo > 0)    Mfree(pinfo);
  462.     erasemsg();
  463.     return (ret);
  464. }
  465.  
  466.  
  467. /*
  468.  * get root sector informations and write them into that sector 
  469.  */
  470.  
  471. stlayroot(bs, dev, part)
  472. char *bs;
  473. int dev;
  474. PART *part;
  475. {
  476.     int i;
  477.     UWORD sum = 0x1234;
  478.     long cnt, disksiz, prvst;
  479.     char *d, *s;
  480.     extern char bootstop;
  481.     extern char bootend;
  482.  
  483.     /* do the prime partition */
  484.     spart(bs, part, 0, &prvst);    /* set ST partition parameters */
  485.     sbslparm(bs);                /* set bsl parameters */
  486.     Protobt(bs, -1L, -1, 1);        /* make root sector executable */
  487.     if ((ret = putroot(dev, bs, (SECTOR)0)) != OK) {
  488.         return(ERROR);
  489.     }
  490.     if (ext == NO_EXT)    return OK;        /* no extended partition */
  491.     /* do the extended partitions */
  492.     extsiz = part[ext].p_siz;
  493.     for (i = 4; i < npart; i++)    {
  494.         if (!(part[i].p_flg & P_EXISTS))    {     /* skip if not exists */
  495.             return OK;
  496.         }
  497.         spart(bs, part, i, &prvst);    /* set IBM partition parameters */
  498.         if (putroot(dev, bs, part[i].p_st) != OK) {
  499.             return(ERROR);
  500.         }
  501.     }
  502.     return OK;
  503. }
  504.  
  505.  
  506.  
  507.  
  508. /*
  509.  * Put information into the root structure
  510.  */
  511.  
  512. spart(image, pinfo, pnm, prvst)
  513.  
  514. char *image;            /* root sector buffer */
  515. register PART *pinfo;    /* partition information */
  516. int pnm;                /* partition number */
  517. long *prvst;            /* The previous partition start sector */
  518.  
  519. {
  520.     PART *rpart;
  521.     long numcyl;
  522.     int i, j;
  523.  
  524.     if (pnm)     {
  525.         fillbuf(image, 512L, 0L);
  526.     }
  527.     rpart = &((RSECT *)(image + 0x200 - sizeof(RSECT)))->hd_p[0];
  528.     if (pnm < 4)    {
  529.         for (i = 0; i < NPARTS; i++, rpart++)    {
  530.             if (pinfo->p_flg & P_EXISTS)    {
  531.                 rpart->p_flg = P_EXISTS;
  532.                 for (j = 0; j < 3; j++)
  533.                     rpart->p_id[j] = pinfo->p_id[j];
  534.                 rpart->p_st = pinfo->p_st;
  535.                 rpart->p_siz = pinfo->p_siz;
  536.             } else {
  537.                 rpart->p_flg = 0;
  538.                 for (j = 0; j < 3; j++)
  539.                     rpart->p_id[j] = 0;
  540.                 rpart->p_st = 0L;
  541.                 rpart->p_siz = 0L;
  542.             }
  543.             pinfo++;
  544.         }
  545.  
  546.     } else {    /* pnm => 4 */
  547.         rpart->p_flg = pinfo[pnm].p_flg;
  548.         for (j = 0; j < 3; j++)
  549.             rpart->p_id[j] = pinfo[pnm].p_id[j];
  550.         rpart->p_st = ROOTSECT;
  551.         rpart->p_siz = pinfo[pnm].p_siz - ROOTSECT;
  552.         rpart++;
  553.         if (((pnm + 1) != npart) && (pinfo[pnm+1].p_flg & P_EXISTS)) { 
  554.             /* need extened partition */
  555.             rpart->p_flg = P_EXISTS;
  556.             rpart->p_id[0] = 'X';
  557.             rpart->p_id[1] = 'G';
  558.             rpart->p_id[2] = 'M';
  559.             rpart->p_siz = pinfo[pnm+1].p_siz;
  560.             rpart->p_st = (pnm == 4) ? (pinfo[4].p_siz) :
  561.                                     (pinfo[pnm].p_siz + *prvst);
  562.             *prvst = rpart->p_st;
  563.         }
  564.  
  565.     }
  566. }
  567.  
  568.  
  569.  
  570. /*
  571.  * Setup partitions on the disk;
  572.  * write boot sectors and zero FATs and root directories.
  573.  *
  574.  */
  575. stlaybs(physdev, pinfo)
  576. int physdev;
  577. register PART *pinfo;
  578. {
  579.     int i, ldev, ret;
  580.     int kindfat;
  581.     SECTOR data, nsect;
  582.     char *devno="X";
  583.     long ndirs;
  584.     UWORD fatsiz;
  585.     BOOT *bs;
  586.     long serialno;
  587.     extern long longrandom();
  588.     extern long cell();
  589.     char *buf;
  590.     long size;
  591.  
  592.     if ((bslsiz = gbslsiz(physdev)) < 0L) {
  593.         return ERROR;
  594.     }
  595.     /* SCAN_BS: pinfo is for scan() and laybs() use */
  596.     if (ext != NO_EXT)    sortpart(pinfo, SCAN_BS);    
  597.  
  598.     for (i = 0; i < npart; ++i, ++pinfo) {
  599.         
  600.         /* don't care if partition does not exist */
  601.         if (!(pinfo->p_flg & P_EXISTS)) {
  602.             return OK;
  603.         }
  604.  
  605.  
  606.     /* estimat the bps */
  607.     /* MAXSECT = 16MB - 8 */
  608.     bps = cell((pinfo->p_siz-7)*BPS, (long)MAXSECT);
  609.  
  610.     /* the real bps */
  611.     bps = BPS * n2power((UWORD)cell(bps, (long)BPS));
  612.     ratio = bps / BPS;
  613.     nsect = pinfo->p_siz / ratio;
  614.  
  615.     size = (long)BPS * ratio;
  616.     if ((buf = (char *)Malloc(size)) <= 0)    {
  617.         if (buf > 0) Mfree((long)buf);
  618.         return ERROR;
  619.     }
  620.  
  621.     /*
  622.      * Install entries in boot sector image;
  623.      * force sector checksum to zero (non-executable);
  624.      * write boot sector to media.
  625.      *
  626.       *    512 bytes/sector
  627.      *    2 or 4 sectors/cluster (partition > 16Mb has 4 spc)
  628.      *    1 reserved sector (for boot)
  629.      *    2 FATs
  630.      *    ... dir slots
  631.      *    ... # sectors
  632.      *    F8 means media is a hard disk
  633.      *    ... FAT size
  634.      *
  635.      */
  636.      
  637.     /* Make a clean boot sector */
  638.     fillbuf(buf, bps, 0L);
  639.     bs = (BOOT *)buf;
  640.         
  641.  
  642.     /* bytes per sector */
  643.     iw((UWORD *)&bs->b_bps[0], (UWORD)bps);
  644.     
  645.     /* sectors per cluster */
  646.     bs->b_spc = SPC;
  647.         
  648.     /* number of reserved sectors */
  649.     iw((UWORD *)&bs->b_res[0], (UWORD)1);
  650.     
  651.     /* number of FATs */
  652.     bs->b_nfats = 2;
  653.     
  654.  
  655.     /*
  656.      * Compute root directory size
  657.      * 256 entries, plus fudge on devs > 10Mb
  658.      */
  659.     if (pinfo->p_siz < 0x5000L) ndirs = NUMEN;
  660.     else ndirs = nsect / 80;    /* 1 dir entry per 80 sectors */
  661.     /* round to nearest sector */
  662.     ndirs = (ndirs + ((UWORD)bps/BPDIR - 1)) & ~((UWORD)bps/BPDIR - 1);    
  663.     iw((UWORD *)&bs->b_ndirs[0], (UWORD)ndirs);
  664.     
  665.     /* number of sectors on media (partition) */
  666.     iw((UWORD *)&bs->b_nsects[0], (UWORD)nsect);
  667.  
  668.     /* media descriptor */
  669.     bs->b_media = 0xf8;
  670.  
  671.     /*--------------------------------------------------------------*
  672.      * Compute FAT size                        *
  673.      *                                *
  674.      * Num entries to map the entire partition            *
  675.      *    = partition's size in clusters                *
  676.      *    = partition's size in sectors / spc            *
  677.      *                                *
  678.      * Num entries in FAT                        *
  679.      *    = Num entries to map partition + reserved entries    *
  680.      *    = (partition's size in sectors / spc) + 2        *
  681.      *                                *
  682.      * Num sectors FAT occupies                    *
  683.      *    = Num entries in FAT / Num entries of FAT per sector    *
  684.      *    = Num entries in FAT / (512 / 2)    <16-bit FAT>    *
  685.      *    = ((partition's size in sectors / spc) + 2) / 256 + 1    *
  686.      *                        <+1 to round up>    *
  687.      *--------------------------------------------------------------*/
  688.     fatsiz = ((((nsect / bs->b_spc) + 2) * 2) / bps) + 1;
  689.     iw((UWORD *)&bs->b_spf[0], (UWORD)fatsiz);
  690.  
  691.     /* write the serial number to the bs */ 
  692.     Protobt(bs, 0x01000000, -1, -1);
  693.  
  694.     /*
  695.      * Write partition's boot sector
  696.      */
  697.     forcesum((UWORD *)buf, (UWORD)0);    /* force image checksum */
  698.     if ((ret = wrsects(physdev,(UWORD)ratio,buf,(SECTOR)pinfo->p_st))!= OK) {
  699.         return ERROR;
  700.     }
  701.  
  702.     /*
  703.      * Zero the partition
  704.      */
  705.     if ((ret = zerosect(physdev, (SECTOR)(pinfo->p_st+ratio),
  706.              ((UWORD)((fatsiz*2 + ndirs*BPDIR/bps) * ratio)))) != OK) {
  707.         return ERROR;
  708.     }
  709.              
  710.     /*
  711.      * Make first 2 entries in FATs more IBM-like.
  712.      */
  713.     if ((ret = rdsects(physdev,(UWORD)ratio,buf,
  714.                         (SECTOR)(pinfo->p_st+ratio)))!= 0){
  715.         return ERROR;
  716.     }
  717.     *(UWORD *)&buf[0] = 0xf8ff;
  718.     *(UWORD *)&buf[2] = 0xffff;
  719.     if ((ret = wrsects(physdev,(UWORD)ratio,
  720.                         buf,(SECTOR)(pinfo->p_st+ratio)))!= 0 ||
  721.         (ret = wrsects(physdev,(UWORD)ratio,buf,
  722.                         (SECTOR)(pinfo->p_st+ratio+fatsiz*ratio)))
  723.         != 0) {
  724.         return ERROR;
  725.     }
  726.  
  727.     /*
  728.      * Mark bad sectors recorded in the BSL into the FATs.
  729.      * Calculating parameters:
  730.      *    ldev - from physdev and i.
  731.      *    fat0 - always equals 1.
  732.      *    fatsiz - calculated above.
  733.      *    data - starts after the boot sector, 2 FATs and rootdir.
  734.      */
  735.  
  736.         if (bslsiz > 0) {
  737.             if ((ldev = phys2log(physdev, i)) == ERROR)
  738.                 return ERROR;
  739.             data = (SECTOR)1 + (SECTOR)(fatsiz*2) + (SECTOR)(ndirs*BPDIR/bps);
  740.             bsl2fat(ldev, (SECTOR)ratio, (UWORD)(fatsiz*ratio), 
  741.                                                 data*ratio, MEDIA);
  742.         }
  743.         if (buf > 0) Mfree((long)buf);
  744.     }
  745.     return OK;
  746. }
  747.  
  748.  
  749.  
  750. /*
  751.  * Open virtual workstation.
  752.  *
  753.  */
  754. open_vwork()
  755. {
  756.     int i;
  757.  
  758.     for (i = 0; i < 10;)
  759.     work_in[i++] = 1;
  760.     work_in[10] = 2;
  761.     handle = phys_handle;
  762.     v_opnvwk(work_in, &handle, work_out);
  763. }
  764.  
  765.  
  766. /*
  767.  * Find and redraw all clipping rectangles
  768.  *
  769.  */
  770. do_redraw(xc, yc, wc, hc)
  771. int xc, yc, wc, hc;
  772. {
  773.     GRECT t1, t2;
  774.     int temp[4];
  775.  
  776.     hide_mouse();
  777.     t2.g_x=xc;
  778.     t2.g_y=yc;
  779.     t2.g_w=wc;
  780.     t2.g_h=hc;
  781.     vsf_interior(handle, 1);
  782.     vsf_color(handle, 0);
  783.     wind_get(wi_handle, WF_FIRSTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
  784.     while (t1.g_w && t1.g_h) {
  785.     if (rc_intersect(&t2, &t1)) {
  786.         set_clip(t1.g_x, t1.g_y, t1.g_w, t1.g_h);
  787.         temp[0] = xwork;
  788.         temp[1] = ywork;
  789.         temp[2] = xwork + wwork - 1;
  790.         temp[3] = ywork + hwork - 1;
  791.         v_bar(handle, temp);
  792.     }
  793.     wind_get(wi_handle, WF_NEXTXYWH, &t1.g_x, &t1.g_y, &t1.g_w, &t1.g_h);
  794.     }
  795.  
  796.     show_mouse();
  797. }
  798.  
  799.  
  800. /*
  801.  * Hide the mouse.
  802.  *
  803.  */
  804. hide_mouse()
  805. {
  806.     if (!hidden) {
  807.     graf_mouse(M_OFF, 0L);
  808.     hidden = TRUE;
  809.     }
  810. }
  811.  
  812.  
  813. /*
  814.  * Show the mouse.
  815.  *
  816.  */
  817. show_mouse() 
  818. {
  819.     if (hidden) {
  820.     graf_mouse(M_ON, 0L);
  821.     hidden = FALSE;
  822.     }
  823. }
  824.  
  825.  
  826. /*
  827.  * Set clipping rectangle.
  828.  *
  829.  */
  830. set_clip(x, y, w, h)
  831. int x, y, w, h;
  832. {
  833.     int clip[4];
  834.  
  835.     clip[0] = x;
  836.     clip[1] = y;
  837.     clip[2] = x + w;
  838.     clip[3] = y + h;
  839.     vs_clip(handle, 1, clip);
  840. }
  841.  
  842.  
  843. /*
  844.  * "Execute" form,
  845.  * return thingy that caused the exit.
  846.  *
  847.  */
  848. execform(tree)
  849. OBJECT tree[];
  850. {
  851.     int thingy;
  852.  
  853.     ARROW_MOUSE;
  854.     dsplymsg(tree);
  855.     thingy = form_do(tree, 0);
  856.     erasemsg();
  857.     BEE_MOUSE;
  858.     return thingy;
  859. }
  860.  
  861.  
  862. /*
  863.  *  Display a dialogue box on the screen.
  864.  *    Input:
  865.  *        tree - object tree for dialogue box to be displayed.
  866.  *    Output:
  867.  *        formw, formh, sx, sy, lx, ly - dimensions of box.
  868.  */
  869. dsplymsg(tree)
  870. OBJECT *tree;
  871. {
  872.     form_center(tree,&lx, &ly, &formw, &formh);
  873.  
  874.     /*
  875.     sx = lx + formw / 2;
  876.     sy = ly + formh / 2;
  877.     */
  878.     
  879.     form_dial(1, 0, 0, 0, 0, lx, ly, formw, formh);
  880.     objc_draw(tree, 0, MAX_DEPTH, 0, 0, wdesk, hdesk);
  881. }
  882.  
  883.  
  884. /*
  885.  *  Erase a dialogue box from the screen.
  886.  *    Input:
  887.  *        formw, formh, sx, sy, lx, ly - dimensions of box.
  888.  */
  889. erasemsg()
  890. {
  891.     form_dial(3, 0, 0, 0, 0, lx, ly, formw, formh);
  892. }
  893.  
  894.  
  895.  
  896. /*
  897.  *  Make a long (4-byte) random.
  898.  */ 
  899. long
  900. longrandom()
  901. {
  902.     long pattern;
  903.     
  904.     pattern = Random();
  905.     pattern <<= 16;
  906.     pattern ^= Random();
  907.     
  908.     return (pattern);
  909. }
  910.  
  911. changeid(part)
  912. PART *part;
  913. {
  914.     int i;
  915.     long psiz;
  916.  
  917.     for(i = 0; i < npart; i++)    {
  918.         if (i == ext)    continue;
  919.         if (!(part[i].p_flg & P_EXISTS)) return OK;
  920.         if (i > 3)    {
  921.             psiz = part[i].p_siz - ROOTSECT;
  922.         } else {
  923.             psiz = part[i].p_siz;
  924.         }
  925.         if (psiz < MB16)    {
  926.             part[i].p_id[0] = 'G';
  927.             part[i].p_id[1] = 'E';
  928.             part[i].p_id[2] = 'M';
  929.         } else {
  930.             part[i].p_id[0] = 'B';
  931.             part[i].p_id[1] = 'G';
  932.             part[i].p_id[2] = 'M';
  933.         }
  934.     }
  935. }
  936.  
  937.